#ifndef DISPATCHER_H_
#define DISPATCHER_H_
/**
 * The Dispatcher class is used to scedule work units.  A dispatcher is an
 * association of a ProcessingUnit with a set of WorkUnits
 **/
#include <list>
#include <WorkUnit/WorkUnit.h>

namespace ComputingObjects
{

class ProcessingUnit;
class WorkUnit;

class DispatchObserver;

class Dispatcher
{
	friend class DispatchObserver;
public:
	Dispatcher(ProcessingUnit& processor);
	virtual ~Dispatcher();
	
	virtual void addWorkUnit(SharedWorkUnit work);
	
	virtual void execute() = 0;
	
	
protected:
	ProcessingUnit& myProcessor;
	std::list<SharedWorkUnit> myDispatchQueue;
	
	/* Implementors of dispatch must call the notifyDispatch method when
	 * a work unit is dispatched */
	virtual void dispatch(SharedWorkUnit unit) = 0;
	void notifyDispatch(SharedWorkUnit unit);
private:
	std::list<DispatchObserver*> myObservers;
	void addObserver(DispatchObserver* anObserver);
	void removeObserver(DispatchObserver* anObserver);
};

class DispatchObserver
{
public:
	
	DispatchObserver(Dispatcher& dispatcher);
	virtual ~DispatchObserver();
	
	virtual void notifyStarted() = 0;
	virtual void notifyStopped() = 0;
	virtual void notifyDispatch(SharedWorkUnit unit) = 0;

	Dispatcher& getDispatcher() 
	{
		return myDispatcher;
	}
	
protected:
	Dispatcher& myDispatcher;
};

}

#endif /*DISPATCHER_H_*/
